package org.dlsu.mt.parser.dictionary;

/**
 * made by LEFT thesis group
 *
 * monolingual dictionary module
 *
 * CollocationList class
 * acts as a list of collocation where elements can be retrieved iteratively and elements can be checked whether they
 * are already found inside the list
 */

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

public class CollocationList
{
	private Hashtable<String, Collocation> elements;
	/**
	 * primary storage of the list
	 * takes as key the value and part of speech of the word separated by a space
	 */
	 
	private Vector<Collocation> iterator; //iterator in order for elements to be retrieved by some order
	private boolean iteratorActive; //flag that indicates whether the iterator is active
	private int count; //element count
	
	public CollocationList()
	{
		/**
		 * constructor with no parameters
		 * initializes the hashtable with no elements
		 */
		elements = new Hashtable();
		iterator = null;
		iteratorActive = false;
		count = -1;
	}
	
	public CollocationList(Hashtable<String,Collocation> elements)
	{
		/**
		 * constructor that takes in a hashtable as its parameter that will serve as the initial elements of the list
		 */
		this.elements = elements;
		iterator = null;
		iteratorActive = false;
		count = -1;
	}
	
	public boolean addElement(String value, String pos)
	{
		/**
		 * adds a new element to the list if it is not yet found in the list
		 * takes as parameter the value and part of speech of the word
		 * returns true if the element is successfully added
		 * returns false if the element is already found in the list
		 */
		if(elements.containsKey(value+" "+pos))
			return false;
		else
		{
			elements.put(value+" "+pos,new Collocation(value, pos));
			if(iteratorActive)
			{
				iterator.addElement(new Collocation(value, pos));
			}
			return true;
		}
	}
	
	public boolean addElement(Collocation c)
	{
		/**
		 * adds a new element to the list if it is not yet found in the list
		 * takes as parameter a collocation object
		 * returns true if the element is successfully added
		 * returns false if the element is already found in the list
		 */
		if(elements.containsKey(c.getValue()+" "+c.getPOS()))
			return false;
		else
		{
			elements.put(c.getValue()+" "+c.getPOS(),c);
			if(iteratorActive)
			{
				iterator.addElement(c);
			}
			return true;
		}
	}
	
	public boolean removeElement(String key)
	{
		/**
		 * removes the element from the list
		 * takes as parameter the key, which is the value and part of speech of the word
		 * concatenated as one string and separated by a single space
		 * returns true if remove is successful
		 * returns false if element is not found in the list
		 */
		if(elements.remove(key) == null)
		{
			return false;
		}
		else
		{
			if(iteratorActive)
			{
				int i =0;
				boolean found = false;
				Function temp = new Function(key);
				while(!found&&i<iterator.size())
				{
					if(iterator.get(i).equals(temp))
					{
						iterator.remove(i);
						found = true;
					}
					i++;
				}
			}
			return true;
		}
	}
	
	public boolean removeElement(String value, String pos)
	{
		/**
		 * removes the element from the list
		 * takes as parameter the value and part of speech of the word
		 * returns true if remove is successful
		 * returns false if element is not found in the list
		 */
		return removeElement(value+" "+pos);
	}
	
	public boolean contains(String key)
	{
		/**
		 * checks if element is found in the list
		 * takes as parameter the key, which is the value and part of speech of the word
		 * concatenated as one string and separated by a single space
		 */
		return elements.containsKey(key);
	}
	
	public boolean contains(String value, String pos)
	{
		/**
		 * checks if element is found in the list
		 * takes as parameter the value and part of speech of the word
		 */
		return contains(value+" "+pos);
	}
	
	public void resetIterator()
	{
		/**
		 * starts the iterator
		 * enables the list to be accessed like a vector
		 */
		Enumeration<Collocation> enumer = elements.elements();
		iterator = new Vector();
		while(enumer.hasMoreElements())
		{
			iterator.addElement(enumer.nextElement());
		}
		iteratorActive = true;
		count = 0;
	}
	
	public void stopIterator()
	{
		/**
		 * stops the iterator
		 */
		iterator = null;
		iteratorActive = false;
		count = -1;
	}
	
	public Collocation getItem(int index)
	{
		/**
		 * note: this method only works when the iterator is active
		 * otherwise, it will always return null
		 *
		 * imitates the get method of a vector
		 */
		if(!iteratorActive)
			return null;
		else
		{
			if(iterator.size()<=index)
				return null;
			else
				return iterator.get(index);
		}
	}
	
	public boolean hasMoreElements()
	{
		/**
		 * note: this method only works when the iterator is active
		 * otherwise, it will always return false
		 *
		 * imitates the method with the same name of an Enumeration object
		 */
		if(!iteratorActive)
			return false;
		else
		{
			if(count<iterator.size())
				return true;
			else
				return false;
		}
	}
	
	public Collocation nextElement()
	{
		/**
		 * note: this method only works when the iterator is active
		 * otherwise, it will always return null
		 *
		 * gets the next element from the iterator and increments it to point to the next element
		 */
		if(!iteratorActive)
			return null;
		else
		{
			if(count<iterator.size())
			{
				count++;
				return iterator.get(count-1);
			}
			else
				return null;
		}
	}
	
	public Collocation previousElement()
	{
		/**
		 * note: this method only works when the iterator is active
		 * otherwise, it will always return null
		 *
		 * gets the previous element from the list
		 * can be used for backtracking
		 * the pointer to the current element in the iterator will not change
		 */
		if(!iteratorActive)
			return null;
		else
		{
			if(count<iterator.size())
			{
				return iterator.get(count-1);
			}
			else
				return null;
		}
	}
	
	public boolean iterationActive()
	{
		/**
		 * returns the state of the iterator, whether it is active of not
		 */
		return iteratorActive;
	}
}